package com.bruce.algorithm.course.array;

/**
 * @author luotuan
 * @Description
 * @create 2020-07-14 17:35
 **/
public class MyList {
    private int size;
    private int[] elements;
    private static final int DEFAULT_CAPACITY = 10;
    private static final int ELEMENT_NOT_FOUND = -1;

    public MyList(int capacity) {
        capacity = (capacity < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : capacity;
        this.elements = new int[capacity];
    }

    public MyList() {
        this(DEFAULT_CAPACITY);
    }

    public int set(int index, int element) {
        rangeCheck(index);
        int old = elements[index];
        elements[index] = element;
        return old;
    }

    public void add(int element) {
        add(size, element);
    }

    public void add(int index, int element) {
        rangeCheckForAdd(index);
        ensureCapacity(index);
        for (int i = size - 1; i >= index; i--) {
            elements[i + 1] = elements[i];
        }
        elements[index] = element;
        size++;
    }

    public int remove(int index) {
        rangeCheck(index);
        int old = elements[index];
        while (index < size) {
            elements[index] = elements[index++];
        }
        size--;
        return old;
    }

    public int indexOf(int element) {
        for (int i = 0; i < size; i++) {
            if (elements[i] == element) {
                return i;
            }
        }
        return ELEMENT_NOT_FOUND;
    }

    public boolean contains(int element) {
        return indexOf(element) != ELEMENT_NOT_FOUND;
    }

    public int get(int index) {
        rangeCheck(index);
        return elements[index];
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    public void clear() {
        size = 0;
    }

    private void outOfBounds(int index) {
        throw new ArrayIndexOutOfBoundsException("集合越界异常:index【" + index + "】");
    }

    public void rangeCheck(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

    private void ensureCapacity(int capacity){
        int oldCapacity = elements.length;
        if(oldCapacity>=capacity){
            return;
        }
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        int[] newElements = new int[newCapacity];
        for(int i=0;i<size;i++){
            newElements[i] = elements[i];
        }
        elements = newElements;
    }

    public void rangeCheckForAdd(int index) {
        if (index < 0 || index >= size) {
            outOfBounds(index);
        }
    }

}
